import tkinter as tk
from tkinter import filedialog, messagebox
from pathlib import Path
from docx import Document
import os
import threading


class WordMergerApp:
    """Word文档合并工具"""
    
    def __init__(self, root):
        self.root = root
        self.root.title("Word文档合并工具")
        self.root.geometry("600x400")
        self.root.resizable(False, False)
        
        # 居中显示窗口
        self.center_window()
        
        # 选中的文件夹路径
        self.folder_path = None
        
        # 创建UI
        self.create_widgets()
    
    def center_window(self):
        """使窗口居中显示"""
        self.root.update_idletasks()
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        x = (self.root.winfo_screenwidth() // 2) - (width // 2)
        y = (self.root.winfo_screenheight() // 2) - (height // 2)
        self.root.geometry(f'{width}x{height}+{x}+{y}')
    
    def create_widgets(self):
        """创建界面组件"""
        # 文件夹选择框架
        folder_frame = tk.Frame(self.root, pady=10)
        folder_frame.pack(fill=tk.X, padx=20)
        
        self.folder_label = tk.Label(
            folder_frame,
            text="未选择文件夹",
            bg="#f0f0f0",
            anchor="w",
            padx=10,
            pady=10,
            relief=tk.SUNKEN
        )
        self.folder_label.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        select_btn = tk.Button(
            folder_frame,
            text="选择文件夹",
            command=self.select_folder,
            padx=15,
            pady=10,
            bg="#4CAF50",
            fg="black",
            font=("Arial", 10, "bold"),
            cursor="hand2"
        )
        select_btn.pack(side=tk.RIGHT, padx=(10, 0))
        
        # 文件列表框架
        list_frame = tk.Frame(self.root, pady=10)
        list_frame.pack(fill=tk.BOTH, expand=True, padx=20)
        
        list_label = tk.Label(
            list_frame,
            text="检测到的Word文件:",
            font=("Arial", 10),
            anchor="w"
        )
        list_label.pack(anchor="w")
        
        # 文件列表（带滚动条）
        list_container = tk.Frame(list_frame)
        list_container.pack(fill=tk.BOTH, expand=True, pady=(5, 0))
        
        scrollbar = tk.Scrollbar(list_container)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        self.file_listbox = tk.Listbox(
            list_container,
            yscrollcommand=scrollbar.set,
            font=("Arial", 9),
            selectmode=tk.SINGLE
        )
        self.file_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=self.file_listbox.yview)
        
        # 状态标签
        self.status_label = tk.Label(
            self.root,
            text="请选择包含Word文档的文件夹",
            font=("Arial", 9),
            fg="#666"
        )
        self.status_label.pack(pady=(0, 10))
        
        # 合并按钮
        self.merge_btn = tk.Button(
            self.root,
            text="开始合并",
            command=self.start_merge,
            padx=30,
            pady=12,
            bg="#1976D2",
            fg="black",
            font=("Arial", 11, "bold"),
            cursor="hand2",
            state=tk.DISABLED
        )
        self.merge_btn.pack(pady=(0, 20))
    
    def select_folder(self):
        """选择文件夹"""
        folder = filedialog.askdirectory(title="选择包含Word文档的文件夹")
        if folder:
            self.folder_path = folder
            self.folder_label.config(text=folder)
            self.scan_word_files()
    
    def scan_word_files(self):
        """扫描文件夹中的Word文件"""
        if not self.folder_path:
            return
        
        # 清空列表
        self.file_listbox.delete(0, tk.END)
        
        # 获取文件夹中的所有文件
        folder = Path(self.folder_path)
        all_files = [f for f in folder.iterdir() if f.is_file()]
        
        # 检查是否有非docx文件
        non_docx_files = [f for f in all_files if f.suffix.lower() != '.docx']
        
        if non_docx_files:
            # 如果存在非docx文件，显示错误提示
            non_docx_names = '\n'.join([f.name for f in non_docx_files[:5]])  # 最多显示5个
            if len(non_docx_files) > 5:
                non_docx_names += f'\n... 等共{len(non_docx_files)}个非docx文件'
            
            messagebox.showerror(
                "文件格式错误",
                f"文件夹中包含非docx格式的文件！\n\n"
                f"只支持.docx格式的文件，请确保文件夹中\n"
                f"只包含docx文件后再试。\n\n"
                f"检测到的非docx文件：\n{non_docx_names}"
            )
            
            self.folder_path = None
            self.folder_label.config(text="未选择文件夹")
            self.status_label.config(
                text="文件夹中包含非docx文件，请重新选择",
                fg="#F44336"
            )
            self.merge_btn.config(state=tk.DISABLED)
            return
        
        # 只查找docx文件
        word_files = list(folder.glob('*.docx'))
        
        # 排序并显示
        word_files.sort()
        
        if word_files:
            for file in word_files:
                self.file_listbox.insert(tk.END, file.name)
            
            self.status_label.config(
                text=f"找到 {len(word_files)} 个docx文件",
                fg="#4CAF50"
            )
            self.merge_btn.config(state=tk.NORMAL)
        else:
            self.status_label.config(
                text="文件夹中没有docx文件",
                fg="#F44336"
            )
            self.merge_btn.config(state=tk.DISABLED)
    
    def start_merge(self):
        """开始合并（在新线程中执行）"""
        # 禁用按钮，防止重复点击
        self.merge_btn.config(state=tk.DISABLED)
        
        # 在新线程中执行合并操作
        thread = threading.Thread(target=self.merge_documents, daemon=True)
        thread.start()
    
    def merge_documents(self):
        """合并Word文档"""
        try:
            self.status_label.config(text="正在合并文档...", fg="#2196F3")
            
            if not self.folder_path:
                raise Exception("未选择文件夹")
            
            folder = Path(self.folder_path)
            word_files = []
            
            # 收集所有docx文件
            word_files = list(folder.glob('*.docx'))
            
            word_files.sort()
            
            if not word_files:
                raise Exception("没有找到docx文件")
            
            # 创建新文档
            merged_doc = Document()
            
            # 合并每个文档
            for i, file_path in enumerate(word_files):
                try:
                    # 只处理docx文件
                    if file_path.suffix.lower() == '.docx':
                        doc = Document(str(file_path))
                        
                        # 如果不是第一个文档，添加分页符
                        if i > 0:
                            merged_doc.add_page_break()
                        
                        # 复制所有段落
                        for paragraph in doc.paragraphs:
                            new_para = merged_doc.add_paragraph(paragraph.text)
                            # 复制段落样式
                            new_para.style = paragraph.style
                        
                        # 复制所有表格
                        for table in doc.tables:
                            new_table = merged_doc.add_table(
                                rows=len(table.rows),
                                cols=len(table.columns)
                            )
                            # 复制表格内容
                            for row_idx, row in enumerate(table.rows):
                                for col_idx, cell in enumerate(row.cells):
                                    new_table.rows[row_idx].cells[col_idx].text = cell.text
                    
                except Exception as e:
                    print(f"处理文件 {file_path.name} 时出错: {str(e)}")
                    continue
            
            # 保存合并后的文档
            output_path = folder / "merged.docx"
            merged_doc.save(str(output_path))
            
            # 更新状态
            self.root.after(0, lambda: self.merge_complete(output_path))
            
        except Exception as e:
            # 显示错误
            self.root.after(0, lambda: self.merge_error(str(e)))
    
    def merge_complete(self, output_path):
        """合并完成"""
        self.status_label.config(
            text=f"合并成功！文件已保存",
            fg="#4CAF50"
        )
        self.merge_btn.config(state=tk.NORMAL)
        
        # 显示成功消息
        result = messagebox.showinfo(
            "合并成功",
            f"文档已成功合并！\n\n保存位置：\n{output_path}\n\n是否打开文件所在文件夹？"
        )
        
        # 打开文件夹
        if result == 'ok':
            os.system(f'open "{output_path.parent}"')
    
    def merge_error(self, error_msg):
        """合并出错"""
        self.status_label.config(
            text="合并失败",
            fg="#F44336"
        )
        self.merge_btn.config(state=tk.NORMAL)
        
        messagebox.showerror(
            "合并失败",
            f"合并文档时出错：\n{error_msg}"
        )


def main():
    """主函数"""
    root = tk.Tk()
    app = WordMergerApp(root)
    root.mainloop()


if __name__ == "__main__":
    main()
